t23.add .k .v .tree .tree1 :-
	insertT23 .k .v .tree .tree1 ! #

t23.search .k .v (L .k .v) #
t23.search .k .v (T2 .n0 .p .n1) :- select
	(compare .k .p => t23.search .k .v .n0)
	(t23.search .k .v .n1) #
t23.search .k .v (T3 .n0 .p0 .n1 .p1 .n2) :- select
	(compare .k .p0 => t23.search .k .v .n0)
	(compare .k .p1 => t23.search .k .v .n1)
	(t23.search .k .v .n2) #

t23.replace .k .v (L .k .) (L .k .v) #
t23.replace .k .v (T2 .n0 .p .n1) .tree1 :-
	select (compare .k .p =>
		t23.replace .k .v .n0 .newn0, .tree1 = T2 .newn0 .p .n1
	) (
		t23.replace .k .v .n1 .newn1, .tree1 = T2 .n0 .p .newn1
	) #
t23.replace .k .v (T3 .n0 .p0 .n1 .p1 .n2) .tree1 :-
	select (compare .k .p0 =>
		t23.replace .k .v .n0 .newn0, .tree1 = T3 .newn0 .p0 .n1 .p1 .n2
	) (compare .k .p1 =>
		t23.replace .k .v .n1 .newn1, .tree1 = T3 .n0 .p0 .newn1 .p1 .n2
	) (
		t23.replace .k .v .n2 .newn2, .tree1 = T3 .n0 .p0 .n1 .p1 .newn2
	) #

insertT23 .k .v $ (L .k .v) #

insertT23 .k0 .v0 (L .k1 .v1) (T2 (L .k0 .v0) .k1 (L .k1 .v1)) :-
	compare .k0 .k1 #

insertT23 .k1 .v1 (L .k0 .v0) (T2 (L .k0 .v0) .k1 (L .k1 .v1)) :-
	compare .k0 .k1 #

insertT23 .k .v (T2 .n0 .p .n1) .tree1 :-
	compare .k .p, insertT23 .k .v .n0 .newn0,
	mergeT2L (T2 .newn0 .p .n1) .tree1 #

insertT23 .k .v (T2 .n0 .p .n1) .tree1 :-
	compare .p .k, insertT23 .k .v .n1 .newn1,
	mergeT2R (T2 .n0 .p .newn1) .tree1 #

insertT23 .k .v (T3 .n0 .p0 .n1 .p1 .n2) .tree1 :-
	compare .k .p0, insertT23 .k .v .n0 .newn0,
	mergeT3L (T3 .newn0 .p0 .n1 .p1 .n2) .tree1 #

insertT23 .k .v (T3 .n0 .p0 .n1 .p1 .n2) .tree1 :-
	compare .p0 .k, compare .k .p1,
	insertT23 .k .v .n1 .newn1,
	mergeT3M (T3 .n0 .p0 .newn1 .p1 .n2) .tree1 #

insertT23 .k .v (T3 .n0 .p0 .n1 .p1 .n2) .tree1 :-
	compare .p1 .k, insertT23 .k .v .n2 .newn2,
	mergeT3R (T3 .n0 .p0 .n1 .p1 .newn2) .tree1 #

mergeT2L (T2 (T2 .n0 .p0 .n1) .p1 .n2) (T3 .n0 .p0 .n1 .p1 .n2) :- ! #
mergeT2L .t .t #

mergeT2R (T2 .n0 .p0 (T2 .n1 .p1 .n2)) (T3 .n0 .p0 .n1 .p1 .n2) :- ! #
mergeT2R .t .t #

mergeT3L (T3 (T2 .n0 .p0 .n1) .p1 .n2 .p2 .n3)
	(T2 (T2 .n0 .p0 .n1) .p1 (T2 .n2 .p2 .n3)) :- ! #
mergeT3L .t .t #

mergeT3M (T3 .n0 .p0 (T2 .n1 .p1 .n2) .p2 .n3)
	(T2 (T2 .n0 .p0 .n1) .p1 (T2 .n2 .p2 .n3)) :- ! #
mergeT3M .t .t #

mergeT3R (T3 .n0 .p0 .n1 .p1 (T2 .n2 .p2 .n3))
	(T2 (T2 .n0 .p0 .n1) .p1 (T2 .n2 .p2 .n3)) :- ! #
mergeT3R .t .t #
